iT邦幫忙

2023 iThome 鐵人賽

DAY 5
0

在本系列文中,所有的程式碼以及測試都可以在 should-i-use-fp-ts 找到,今日的範例放在 src/day-05 並且有習題和測試可以讓大家練習。

Pointfree

Point-free style — aims to reduce some of the visual clutter by removing unnecessary parameter-argument mapping."
- Kyle Simpson

pointfreefunctional programming 中的一種特性,也可以稱為 tacit (無參數) programming
pointfree 的概念是在特定情況下函數使用不需要標注參數(點 point),這個特性在之後的程式常常使用到,有助於讓我們的程式更加的簡潔,專注於如何宣告我們的結果。

先來一段簡單的範例吧,這邊使用 array 的 function 來示範,將 list 中的所有元素都加一,然後把所有的數字都改成字串。

const list = [1, 2, 3, 4, 5];

# point style
list.map(x => x + 1)
	.map(x => x.toString()); // ['2', '3', '4', '5', '6']

# pointfree
const inc = (x: number) => x + 1;
const toString = (x: number) => x.toString();

list.map(inc)
	.map(toString); // ['2', '3', '4', '5', '6']

或許有些讀者會有疑問,原本兩行的程式平白變成四行了,這樣是不是 pointfree 反而讓程式變繁複了?

  1. 首先,預先定義的 inc, toString 並不是只用在這裡,他可以廣泛的應用在程式的其他部分。
  2. 其次,這裡關注於實際應用 pointfree 的部分,可以發現這邊更加的語意化,可以將意圖直接敘述出來,這樣可以隱藏不需要的細節,專注在目前的邏輯上。
    (ex. 在 list map 所有元素都進行一次 inc)。

再來說明一下使用 pointfree 的注意事項,如果 pointfree 使用的函數是可以接受多參數的時候,可能會有效果不符預期的情況,一樣使用 array 的 function 來示範。

const list = [1, 2, 3, 4, 5];

list.map(inc)
	.map(toString) // ['2', '3', '4', '5', '6']
	.map(console.log)
// output:
/* '2', 0, ['2', '3', '4', '5', '6']
 * '3', 1, ['2', '3', '4', '5', '6']
 * '4', 2, ['2', '3', '4', '5', '6']
 * '5', 3, ['2', '3', '4', '5', '6']
 * '6', 4, ['2', '3', '4', '5', '6']
 */

會有這樣的結果是由於 console.log 本身接收的參數是 (...data: any[]),而 pointfree 會接收所有 callback 傳過來的函數(ex. map => (value, index, array)),使用上有這點需要稍微注意一下。

今天的主題在 should-i-use-fp-tssrc/day-05 並且有習題和測試可以讓大家練習。

Reference:

聊一聊函数式编程中的pointfree
Pointfree 编程风格指南 - 阮一峰大神寫的,強烈推薦。


上一篇
[Should I use fp-ts?] Day 04 - declarative vs. imperative
下一篇
[Should I use fp-ts?] Day 06 - pipe and flow
系列文
Should I use fp-ts25
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言